#include "TestController.h"

#include "nlohmann/json.hpp"

#include <chrono>
#include <thread>

TestController::TestController()
{
}

TestController::~TestController()
{
}

void TestController::hello(const httplib::Request &req, httplib::Response &res)
{
    std::cout << "**************** headers ****************" << std::endl;
    for (const auto &header : req.headers) {
        std::cout << header.first << ":" << header.second << std::endl;
    }
    res.set_content("<h1 align=\"center\">Hello, World!</h1>", "text/html");
}

void TestController::stream(const httplib::Request &req, httplib::Response &res)
{
    res.set_header("Connection", "keep-alive");

    uint32_t counter = 0;
    res.set_chunked_content_provider("application/json", [counter](size_t offset, httplib::DataSink &sink) mutable {
        std::this_thread::sleep_for(std::chrono::milliseconds(100));

        nlohmann::json json_data;
        json_data["message"] = ++counter;
        std::string chunk    = json_data.dump();
        sink.write(chunk.data(), chunk.size());
        if (counter >= 5) {
            sink.done();
            return false;
        }
        return true;
    });
}

void TestController::multipart(const httplib::Request &req, httplib::Response &res)
{
    // 1. 定义 boundary（随机生成或固定值）
    std::string boundary = "--------------------BOUNDARY_12345";

    // 2. 设置分块传输
    res.set_chunked_content_provider("multipart/mixed; boundary=" + boundary, [boundary](size_t offset, httplib::DataSink &sink) {
        for (;;) {
            std::this_thread::sleep_for(std::chrono::milliseconds(1000));
            // 发送数据（模拟动态生成）
            std::string part = "--" + boundary +
                               "\r\n"
                               "Content-Type: application/json\r\n\r\n"
                               "{\"status\": \"success\"}\r\n\r\n";
            sink.write(part.data(), part.size());
        }

        // 发送结束标记
        std::string end = "--" + boundary + "--\r\n";
        sink.write(end.data(), end.size());

        sink.done(); // 终止传输
        return false;
    });
}

void TestController::getExample(const httplib::Request &req, httplib::Response &res)
{
    std::cout << "receive getExample" << std::endl;

    std::string    id      = req.path_params.at("id");
    nlohmann::json jsonObj = {
        {"result", "success"},
        {"id",     id       }
    };
    res.set_content(jsonObj.dump(), "application/json");
}

void TestController::postExample(const httplib::Request &req, httplib::Response &res)
{
    std::cout << "**************** headers ****************" << std::endl;
    for (const auto &header : req.headers) {
        std::cout << header.first << ":" << header.second << std::endl;
    }

    nlohmann::json reqJson;
    try {
        reqJson = nlohmann::json::parse(req.body);
    } catch (nlohmann::detail::exception &e) {
        nlohmann::json errJson = {
            {"result",  "failure"         },
            {"message", "JSON解析失败"}
        };
        res.set_content(errJson.dump(), "application/json");
        return;
    }

    std::cout << "receive message: " << reqJson.dump() << std::endl;

    nlohmann::json jsonObj = {
        {"result", "success"},
    };
    res.set_content(jsonObj.dump(), "application/json");
}

void TestController::bind(httplib::Server *server)
{
    server->Get("/", [=](const httplib::Request & /*req*/, httplib::Response &res) {
        res.set_redirect("/hello");
    });
    server->Get("/hello", bindController(&TestController::hello, this));
    server->Get("/stream", bindController(&TestController::stream, this));
    server->Get("/multipart", bindController(&TestController::multipart, this));
    server->Get("/hello/:id", bindController(&TestController::getExample, this));
    server->Post("/hello", [&](const httplib::Request &req, httplib::Response &res) {
        postExample(req, res);
    });
}